package stone926.mods.more_enchantments.mixins;

import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.projectile.ShulkerBulletEntity;
import net.minecraft.nbt.NbtCompound;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import stone926.mods.more_enchantments.interfaces.IShulkerBullet;
import stone926.mods.more_enchantments.interfaces.IShulkerEntity;
import stone926.mods.more_enchantments.mixins.accessors.StatusEffectInstanceAccessor;

import static stone926.mods.more_enchantments.nbt.CustomNbtKeys.SHULKER_BULLET.EXTRA_DAMAGE;
import static stone926.mods.more_enchantments.nbt.CustomNbtKeys.SHULKER_BULLET.FLASH;

@Mixin(ShulkerBulletEntity.class)
public class ShulkerBulletEntityMixin implements IShulkerBullet {

  private float bulletDamage = 0F;
  private int flash = 0;

  @Override
  public float getExtraBulletDamage() {
    return bulletDamage;
  }

  @Override
  public void setExtraBulletDamage(float damage) {
    bulletDamage = damage;
  }

  @Override
  public int getFlash() {
    return flash;
  }

  @Override
  public void setFlash(int flash) {
    this.flash = flash;
  }

  @Inject(method = "readCustomDataFromNbt", at = @At("HEAD"))
  private void readCustomDateFromNbt(NbtCompound nbt, CallbackInfo ci) {
    if (nbt.contains(EXTRA_DAMAGE)) setExtraBulletDamage(nbt.getFloat(EXTRA_DAMAGE));
    if (nbt.contains(FLASH)) setFlash(nbt.getInt(FLASH));
  }

  @Inject(method = "writeCustomDataToNbt", at = @At("HEAD"))
  private void writeCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) {
    nbt.putFloat(EXTRA_DAMAGE, getExtraBulletDamage());
    nbt.putInt(FLASH, getFlash());
  }

  @Redirect(method = "onEntityHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;damage(Lnet/minecraft/entity/damage/DamageSource;F)Z"))
  private boolean redirectDamage(Entity entity, DamageSource source, float amount) {
    return entity.damage(source, amount + getExtraBulletDamage());
  }

  @Redirect(method = "onEntityHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;addStatusEffect(Lnet/minecraft/entity/effect/StatusEffectInstance;Lnet/minecraft/entity/Entity;)Z"))
  private boolean handleLevitation(LivingEntity livingEntity, StatusEffectInstance effect, Entity source) {
    Entity owner = ((ProjectileEntity) (Object) this).getOwner();
    if (owner instanceof IShulkerEntity shulker && shulker.levitationAmplifierChanged()) {
      StatusEffectInstance effect2 = new StatusEffectInstance(effect);
      ((StatusEffectInstanceAccessor) effect2).setAmplifier(shulker.getLevitationAmplifier());
      return livingEntity.addStatusEffect(effect2, source);
    } else return livingEntity.addStatusEffect(effect, source);
  }

}
